package com.zhangtai.modules.controller.aouthLogin;


import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.zhangtai.Neusoft.service.NeuEmployeeBaseInfoService;
import com.zhangtai.consts.CommonConstr;
import com.zhangtai.exception.RException;
import com.zhangtai.modules.controller.admin.JobController;
import com.zhangtai.modules.dao.EmployeeInfoDao;
//import com.zhangtai.modules.dao.ssqlDao.JobDaoMssql;
import com.zhangtai.modules.dto.EmployeeCachDto;
import com.zhangtai.modules.entity.employee.EmployeeInfoEntity;
import com.zhangtai.modules.jobTask.CommonJobTask;
import com.zhangtai.modules.service.login.CustomBase64;
import com.zhangtai.modules.service.login.JwtEncodeAndEncode;
import com.zhangtai.utils.CookieUtils;
import com.zhangtai.utils.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RestController
@Slf4j
@Api(tags="员工自助登录接口")
@RequestMapping("/member")
public class MemberLoginController {

    @Autowired
    private EmployeeInfoDao employeeInfoDao;
//    @Autowired
//    private JobDaoMssql jobDaoMssql;

    @Autowired
    private JwtEncodeAndEncode jwtEncodeAndEncode;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private JobController jobController;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private CommonJobTask commonJobTask;
//    @Autowired
//    private NeuEmployeeBaseInfoService neuEmployeeBaseInfoService;

    private String url="https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=%s&code=%s";
    private String GET_USER_INFO="https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=%s&userid=%s";

    private String GET_DEPARTMENT="https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s&id=%s";





    @GetMapping("/login")
    @ApiOperation(value="登录接口")
    public R login(@RequestParam("code") String code) throws Exception {
      //  code= URLEncoder.encode(code,"UTF-8");
     //   code= URLDecoder.decode( code, "UTF-8" );

        log.info("code:{}",code);

//        截取用户名
        String s2 = StringUtils.subString(code, "&zu=", "&zt");
        if (StringUtils.isEmpty(s2)){
            return R.error("请求参数中没有账号");
        }
            String zu = CustomBase64.decrypt(s2);
        log.info("zu:{}",zu);

       List<EmployeeInfoEntity>  employeeInfoEntityList = employeeInfoDao.selectList(new QueryWrapper<EmployeeInfoEntity>().eq("useraccount", zu)
               .or().eq("mobile",zu).eq("is_delete", 0));

       if(employeeInfoEntityList.size()>1){
           return R.error("请求参数中存在两天以上数据，请联络管理员");
       }
        EmployeeInfoEntity employeeInfoEntity=employeeInfoEntityList.get(0);
        if (!ObjectUtils.isEmpty(employeeInfoEntity)){
            jwtEncodeAndEncode.encodeMember(employeeInfoEntity); //加密成token并存入到cookie中
            return R.ok();
        }


            employeeInfoEntity = jobController.findEmpByAccount(zu).getData();//从sqlServer中查询
            log.info("本地查不到去ehr查:{}",employeeInfoEntity);

            if (ObjectUtils.isEmpty(employeeInfoEntity)){
                log.info("ehr查询用户为空");
                return R.error("ehr查询用户为空");
            }

        R x = inserOrUpdateEmp(employeeInfoEntity);  //插入员工信息，或者更新员工信息
        if (x != null) return x;

        jwtEncodeAndEncode.encodeMember(employeeInfoEntity); //加密成token并存入到cookie中


        log.info("员工登陆成功:{}",employeeInfoEntity);




        return R.ok();
    }


    /**
     * 其未登录
     * @param code
     * @return
     * @throws Exception
     */
    @GetMapping("/QWLogin")
    @ApiOperation(value="企微登录接口")
    public R preQwLogin(@RequestParam("code") String code) throws Exception {
        //解码code
       // code= URLEncoder.encode(code,"UTF-8");
      //  code=URLDecoder.decode( code, "UTF-8" );
//        log.info("请求的code为：{}",code);
        if (StringUtils.isEmpty(code)) {
            return R.error("code不能为空");
        }
        String acToken = (String) redisTemplate.boundValueOps(CommonConstr.OAUTH_ACCESS_TOKEN_KEY).get();
        if (StringUtils.isEmpty(acToken)) {
            acToken = commonJobTask.gettoken(); //如果获取不到 则重试一次
        }

        String format = String.format(url, acToken, code);

        String forObject = null;
        try {
//            获取userId
            forObject = restTemplate.getForObject(format, String.class);
        } catch (RestClientException e) {
            throw new RException("获取user信息失败", e);
        }
        JSONObject jsonObject = JSON.parseObject(forObject);
        if (ObjectUtils.isEmpty(jsonObject)) {
            return R.error("您尚未在公司企微注册");
        }
        String userId = jsonObject.getString("UserId");
        if (StringUtils.isEmpty(userId)) {
            return R.error("您尚未在公司企微注册");
        }


        String format1 = String.format(GET_USER_INFO, acToken, userId);
//        log.info("根据uid获取用户信息链接:{}",format1);
//        根据userId获取 userInfo
        String forObject1 = restTemplate.getForObject(format1, String.class);
        JSONObject userinfoJsonObject = JSON.parseObject(forObject1);

        String userid = userinfoJsonObject.getString("userid");
        String mobile = userinfoJsonObject.getString("mobile");
        String avatar = userinfoJsonObject.getString("avatar");

        String phone = null;
        boolean b = isPhone(userId);

        if (b) {
            phone = userId;
        } else {
            phone = mobile;
        }

//        根据账号查
        EmployeeInfoEntity employeeInfoEntity = employeeInfoDao.selectOne(new QueryWrapper<EmployeeInfoEntity>().eq("useraccount", userid).
                eq("is_delete", 0));
//        如果根据行号查不到，则根据手机查
        if (ObjectUtils.isEmpty(employeeInfoEntity)&&!StringUtils.isEmpty(phone)){
            employeeInfoEntity = employeeInfoDao.selectOne(new QueryWrapper<EmployeeInfoEntity>().eq("mobile", mobile).
                    eq("is_delete", 0));
        }

        if (!ObjectUtils.isEmpty(employeeInfoEntity)){
            employeeInfoEntity.setAvatar(avatar);
            jwtEncodeAndEncode.encodeMember(employeeInfoEntity); //加密成token并存入到cookie中
            log.info("员工登陆成功:{}",employeeInfoEntity);
            return R.ok();
        }

        employeeInfoEntity = jobController.findEmpByAccount(userid).getData();//从sqlServer中查询

        if (ObjectUtils.isEmpty(employeeInfoEntity)&&!StringUtils.isEmpty(phone)){

//            employeeInfoEntity=jobDaoMssql.findEmpByMobile(phone);
        }

        if (ObjectUtils.isEmpty(employeeInfoEntity)){
            return R.error("查不到该用户");
        }

        R x = inserOrUpdate(avatar, phone, employeeInfoEntity);  // 插入或修改员工数据
        if (x != null) return x;


        jwtEncodeAndEncode.encodeMember(employeeInfoEntity); //加密成token并存入到cookie中
        log.info("员工登陆成功:{}",employeeInfoEntity);






        return R.ok();
    }

    private R inserOrUpdate(String avatar, String phone, EmployeeInfoEntity employeeInfoEntity) {
        String usercode = employeeInfoEntity.getCode();
        if (StringUtils.isEmpty(usercode)){
            return R.error("从ehr数据库中获取的工号为空");
        }

        setJobLevel(employeeInfoEntity); //设置职级
        employeeInfoEntity.setAvatar(avatar);//设置头像
        employeeInfoEntity.setCreateTime(new Date());
        employeeInfoEntity.setUpdateTime(new Date());


        //        根据工号查号
        EmployeeInfoEntity entityInfo = employeeInfoDao.selectOne(new QueryWrapper<EmployeeInfoEntity>().eq("code", usercode).
                eq("is_delete", 0));

//        如果工号为空，则根据身份证和手机号查找
        String idcard = employeeInfoEntity.getIdcard();
        if (ObjectUtils.isEmpty(entityInfo)){
            entityInfo = employeeInfoDao.selectOne(new QueryWrapper<EmployeeInfoEntity>().eq("idcard", idcard).eq("mobile", phone).
                    eq("is_delete", 0));
        }


        if (ObjectUtils.isEmpty(entityInfo)){

            employeeInfoDao.insert(employeeInfoEntity);

        }else {
            employeeInfoEntity.setOid(null);
            int i = employeeInfoDao.update(employeeInfoEntity, new QueryWrapper<EmployeeInfoEntity>().eq("code", usercode));
//            如果根据工号匹配为空，则根据手机和身份证进行匹配
            if (i<=0){
                int j = employeeInfoDao.update(employeeInfoEntity, new QueryWrapper<EmployeeInfoEntity>().eq("idcard", idcard).eq("mobile", phone)
                        .eq("is_delete", 0));
                if (j<=0){
                    return R.error("根据手机和身份证进行匹配失败");
                }
            }

        }
//        neuEmployeeBaseInfoService.saveAndUpdateEmployeeInfoOne(employeeInfoEntity.getCode(),employeeInfoEntity.getOid()+"");
        return null;
    }


    @GetMapping("/getUserInfo")
    @ApiOperation(value="获取员工登录信息")
    public R<JSONObject> getUserInfo(HttpServletRequest request) throws Exception{


        String cookieValue = CookieUtils.getCookieValue(request, "MemberToken");
//        String cookieValue = request.getHeader("Authorization").replace("Bearer ","");

        if (StringUtils.isEmpty(cookieValue)){
            return R.error("cookieValue为空");
        }
        String decode=null;
        try {
//            log.info("开始解析");
            decode = jwtEncodeAndEncode.decode(cookieValue);
//            log.info("decode:{}",decode);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RException("token解析失败");
        }
        JSONObject user = JSON.parseObject(decode, JSONObject.class);
        Long id = user.getLong("id");
        String usercode = user.getString("usercode");
//        EmployeeInfoEntity employeeInfoEntity = employeeInfoDao.selectById(id);
        EmployeeCachDto employeeInfoEntity = (EmployeeCachDto) redisTemplate.boundValueOps("employeeInfo" + usercode).get();
        if (!ObjectUtils.isEmpty(employeeInfoEntity)){
            Long jobId = employeeInfoEntity.getJobId();
            String jobName = jobController.getJobName(jobId);
            Long orgId = employeeInfoEntity.getOrgId();
            String orgNameById = jobController.getOrgNameById(orgId);
            Long unitId = employeeInfoEntity.getUnitId();
            String unitName = jobController.getOrgNameById(unitId);
            Long jobLevelId = employeeInfoEntity.getJobLevelId();
            Integer jobLevelType = employeeInfoEntity.getJobLevelType();
            String jobLevel = jobController.getJobLevelNameById(jobLevelId);
            user.put("jobId",jobId);
            user.put("jobLevelId",jobLevelId);
            user.put("jobLevel",jobLevel);
            user.put("jobLevelType",jobLevelType);
            user.put("jobname",jobName);
            user.put("orgname",orgNameById);
            user.put("department",unitName);
            user.put("orgId",orgId);
            user.put("depId",unitId);
            user.put("gender",employeeInfoEntity.getGender());
//            user.put("saying","我是鸡汤");


        }


//        log.info("获取登录用户信息user:{}",user);
        return R.ok(user);


    }

    @GetMapping("/exit")
    @ApiOperation(value="登出")
    public R logOut(HttpServletRequest request, HttpServletResponse response){
        String cookieValue = CookieUtils.getCookieValue(request, "MemberToken");
        if (StringUtils.isEmpty(cookieValue)){
            return R.error("cookieValue为空");
        }
        String decode=null;
        try {
//            log.info("开始解析");
            decode = jwtEncodeAndEncode.decode(cookieValue);
//            log.info("decode:{}",decode);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RException("token解析失败");
        }
        JSONObject user = JSON.parseObject(decode, JSONObject.class);
        String uuid = user.getString("uuid");

        redisTemplate.delete(uuid);
        CookieUtils.deleteCookie(request,response,"MemberToken");
        return R.ok();
    }

    private   boolean isPhone(String phone) {
        String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
        if (phone.length() != 11) {
//            System.out.println("手机号应为11位数");
            return false;
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phone);
            boolean isMatch = m.matches();
            //LogUtil.e(isMatch);
            if (!isMatch) {
//                System.out.println("请填入正确的手机号");
            }
            return isMatch;
        }
    }


    private R inserOrUpdateEmp(EmployeeInfoEntity employeeInfoEntity) {
        employeeInfoEntity.setCreateTime(new Date());
        employeeInfoEntity.setUpdateTime(new Date());

        String userCode = employeeInfoEntity.getCode();
        if (StringUtils.isEmpty(userCode)){
            return R.error("ehr数据库中的工号为空");
        }
        setJobLevel(employeeInfoEntity); //设置职级


        String idcard = employeeInfoEntity.getIdcard();
        String mobile = employeeInfoEntity.getMobile();

        //先根据工号去查询本地
        EmployeeInfoEntity infoEntity = employeeInfoDao.selectOne(new QueryWrapper<EmployeeInfoEntity>().eq("code", userCode).
                eq("is_delete", 0));
        if (ObjectUtils.isEmpty(infoEntity)){

            if (StringUtils.isEmpty(idcard)||StringUtils.isEmpty(mobile)){
                return R.error("身份证或手机号为空");
            }
//            如果根据工号查询为空，再根据身份证和手机查询
            infoEntity = employeeInfoDao.selectOne(new QueryWrapper<EmployeeInfoEntity>().eq("idcard", idcard).eq("mobile", mobile).
                    eq("is_delete", 0));
        }

//        如果根据工号和 身份证/手机去查询 都查不到，则认为是本地没有记录，则新插入一条
        if (ObjectUtils.isEmpty(infoEntity)){
            employeeInfoDao.insert(employeeInfoEntity);  //如果本地库为空，则插入一条数据
        }else {
//            如果本地不为空，则首先用工号匹配，进行更新
            employeeInfoEntity.setOid(null); //把工号置为空，避免工号覆盖
            int i = employeeInfoDao.update(employeeInfoEntity, new QueryWrapper<EmployeeInfoEntity>().eq("code", userCode));
//            如果根据工号更新失败，则根据身份证和手机进行匹配
            if (i<=0){
                int j = employeeInfoDao.update(employeeInfoEntity, new QueryWrapper<EmployeeInfoEntity>().eq("idcard", idcard).
                        eq("mobile", mobile));
                if (j<=0){
                    return R.error("根据身份证和手机号进行匹配失败");
                }
            }
        }
        return null;
    }



    private void setJobLevel(EmployeeInfoEntity employeeInfoEntity) {
        Long professionJoblevelId = employeeInfoEntity.getProfessionJoblevelId();
        Long managementJoblevelId = employeeInfoEntity.getManagementJoblevelId();
        if (managementJoblevelId != null) {
            employeeInfoEntity.setJobLevelType(2); //管理职级
            employeeInfoEntity.setJobLevelId(managementJoblevelId);
        } else {
            employeeInfoEntity.setJobLevelType(1); //专业职级
            employeeInfoEntity.setJobLevelId(professionJoblevelId);
        }
    }



}
